package com.harmonycloud;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

public class DbStoreHelper {

    /**
     * 执行数据库插入操作
     *
     * @param datas     插入数据表中key为列名和value为列对应的值的Map对象的List集合
     * @param tableName 要插入的数据库的表名
     * @return 影响的行数
     * @throws SQLException SQL异常
     */
    public static int insertAll(String tableName, List<Map<String, Object>> datas) throws SQLException {
        /**影响的行数**/
        int affectRowCount = -1;
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            /**从数据库连接池中获取数据库连接**/
            connection = DBConnectionPool.getInstance().getConnection();
            Map<String, Object> valueMap = datas.get(0);
            /**获取数据库插入的Map的键值对的值**/
            Set<String> keySet = valueMap.keySet();
            Iterator<String> iterator = keySet.iterator();
            /**要插入的字段sql，其实就是用key拼起来的**/
            StringBuilder columnSql = new StringBuilder();
            /**要插入的字段值，其实就是？**/
            StringBuilder unknownMarkSql = new StringBuilder();
            Object[] keys = new Object[valueMap.size()];
            int i = 0;
            while (iterator.hasNext()) {
                String key = iterator.next();
                keys[i] = key;
                columnSql.append(i == 0 ? "" : ",");
                columnSql.append(key);

                unknownMarkSql.append(i == 0 ? "" : ",");
                unknownMarkSql.append("?");
                i++;
            }
            /**开始拼插入的sql语句**/
            StringBuilder sql = new StringBuilder();
            sql.append("INSERT INTO ");
            sql.append(tableName);
            sql.append(" (");
            sql.append(columnSql);
            sql.append(" )  VALUES (");
            sql.append(unknownMarkSql);
            sql.append(" )");

            /**执行SQL预编译**/
            preparedStatement = connection.prepareStatement(sql.toString());
            /**设置不自动提交，以便于在出现异常的时候数据库回滚**/
            connection.setAutoCommit(false);
            System.out.println(sql.toString());
            for (int j = 0; j < datas.size(); j++) {
                for (int k = 0; k < keys.length; k++) {
                    preparedStatement.setObject(k + 1, datas.get(j).get(keys[k]));
                }
                preparedStatement.addBatch();
            }
            int[] arr = preparedStatement.executeBatch();
            connection.commit();
            affectRowCount = arr.length;
            System.out.println("成功了插入了" + affectRowCount + "行");
        } catch (Exception e) {
            if (connection != null) {
                connection.rollback();
            }
            e.printStackTrace();
            throw e;
        } finally {
            if (preparedStatement != null) {
                preparedStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
        return affectRowCount;
    }


    public static List<Rule> filterErrorResult(List<Rule> ruleList) throws SQLException {
        RightAndErrorDBTool rightAndErrorDBTool = new RightAndErrorDBTool();
        List<ErrorRelated> errorRelateds = rightAndErrorDBTool.selectErrorRelatedList();
        Map<String, ErrorRelated> maperror = new HashMap<>();
        for (ErrorRelated er : errorRelateds)
            maperror.put(er.getAntecedent(), er);

        List<RightRelated> rightRelateds = rightAndErrorDBTool.selectRightRelatedList();
        Map<String, RightRelated> mapright = new HashMap<>();
        for (RightRelated rr : rightRelateds)
            mapright.put(rr.getAntecedent(), rr);

        if (null != ruleList) {
            for (Iterator iterator = ruleList.iterator(); iterator.hasNext(); ) {
                Rule rule = (Rule) iterator.next();
                String antecedent = rule.getAntecedent();
                if (maperror.containsKey(antecedent)) {
                    if (maperror.get(antecedent).getConsequent().equals(rule.getConsequent())) {
                        rightAndErrorDBTool.updateErrorRelated(maperror.get(antecedent).getId());
                    }
                }

                if (mapright.containsKey(antecedent)) {
                    if (mapright.get(antecedent).getConsequent().equals(rule.getConsequent()))
                        rightAndErrorDBTool.updateRightRelated(mapright.get(rule.getAntecedent()).getId());
                }
            }
        }

        return ruleList;
    }

    public List<Alarm> selectByAppmodelId(Integer appmodelId) throws SQLException {

        List<Alarm> alarmList = new ArrayList<>();
        String sql_query = "select * from t_alarm where type=1 and appmodel_id=" + appmodelId;

        Connection cn = DBConnectionPool.getInstance().getConnection();
        PreparedStatement ps = cn.prepareStatement(sql_query);

        ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                Alarm alarm = new Alarm();
                alarm.setType(rs.getInt("type"));
                alarm.setAlarmContent(rs.getString("alarm_content"));
                alarm.setAlarmDetail(rs.getString("alarm_detail"));
                alarm.setHappendModel(rs.getString("happend_model"));
                alarm.setAppmodelId(rs.getInt("appmodel_id"));
                alarm.setHappendTime(rs.getTimestamp("happend_time"));
                alarm.setAlarmLevel(rs.getInt("alarm_level"));
                alarm.setId(rs.getInt("id"));
                alarm.setAlarmStatus(rs.getInt("alarm_status"));
                alarm.setSubId(rs.getString("sub_id"));
                alarm.setRelatedId(rs.getString("related_id"));
                alarmList.add(alarm);
            }

        if (ps != null)
            ps.close();
        if (cn != null)
            cn.close();

        return alarmList;
    }


    public static void insertList(List<Rule> list) {

        List<Map<String, Object>> listMap = new ArrayList<>();
        for (Rule rule : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("appmodel_id", rule.getAppmodelId());
            map.put("app_name", rule.getAppName());
            map.put("antecedent", rule.getAntecedent());
            map.put("consequent", rule.getConsequent());
            map.put("confidence", rule.getConfidence());
            listMap.add(map);
        }
        try {
            DbStoreHelper.insertAll("rule", listMap);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
